package com.tinem.platform.web.auth.login.code;

import com.tinem.platform.module.pojo.co.SessionKeyEnum;
import com.tinem.platform.module.pojo.vo.error.UserException;
import com.tinem.platform.module.starter.sdk.MessageCode;
import com.tinem.platform.module.starter.web.context.GatewayContext;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
	
	private boolean postOnly = true;
	private String toParameter = "to";
	private String countryMobileCodeParameter = "countryMobileCode";
	private String codeParameter = "code";
	public static final String LOGIN_PROCESSING = "/endpoint/login/mobile.do";

	public CodeAuthenticationFilter() {
        super(new AntPathRequestMatcher(LOGIN_PROCESSING, "POST"));
    }

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
		try {
			GatewayContext.REQUEST_LOCAL.set(request);
			GatewayContext.RESPONSE_LOCAL.set(response);
			if (postOnly && !HttpMethod.POST.name().equals(request.getMethod())) {
				throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
			}

			// 获取请求中的参数值
			String countryMobileCode = obtainCountryMobileCode(request);
			String to = obtainTo(request);
			String code = obtainCode(request);
			Long codeId = obtainCodeId(request,to);
			if(code == null){
				throw new UserException(MessageCode.ERROR_COMMONS_PARAMS,"code");
			}
			if(codeId == null){
				throw new UserException(MessageCode.ERROR_COMMONS_PARAMS,"codeId");
			}
			CodeAuthenticationToken authRequest = new CodeAuthenticationToken(countryMobileCode,to,code,codeId);
			// Allow subclasses to set the "details" property
			setDetails(request, authRequest);
			return this.getAuthenticationManager().authenticate(authRequest);
		}finally {
			GatewayContext.RESPONSE_LOCAL.remove();
			GatewayContext.REQUEST_LOCAL.remove();
		}

	}

	private Long obtainCodeId(HttpServletRequest request,String to) {
		return (Long) request.getSession().getAttribute(SessionKeyEnum.verification_code_send.getKey(to));
	}

	/**
     * 获取手机号
     */
	protected String obtainTo(HttpServletRequest request) {
		return request.getParameter(toParameter);
	}
	protected String obtainCountryMobileCode(HttpServletRequest request) {
		return request.getParameter(countryMobileCodeParameter);
	}
	protected String obtainCode(HttpServletRequest request) {
		return request.getParameter(codeParameter);
	}

	protected void setDetails(HttpServletRequest request, CodeAuthenticationToken authRequest) {
		authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
	}

	public void setPostOnly(boolean postOnly) {
		this.postOnly = postOnly;
	}

}